package rpc.ratelimiter.semaphore;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rpc.ratelimiter.base.AbstractRateLimiterInvoker;
import rpc.spi.annotation.SPIClass;

import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;


@SPIClass
public class SemaphoreRateLimiterInvoker extends AbstractRateLimiterInvoker {
    private final Logger logger = LoggerFactory.getLogger(SemaphoreRateLimiterInvoker.class);
    private Semaphore semaphore;
    private final AtomicInteger counter = new AtomicInteger(0);
    private volatile long lasTime = System.currentTimeMillis();



    @Override
    public void init(int permits, int milliSeconds) {
        super.init(permits, milliSeconds);
        this.semaphore = new Semaphore(permits);
    }

    @Override
    public boolean tryAcquire() {
        logger.info("execute semaphore rate limiter...");
        long currentTime = System.currentTimeMillis();
        if (currentTime - lasTime >= milliSeconds){
            lasTime = currentTime;
            semaphore.release(counter.get());
            counter.set(0);
        }
        boolean result = semaphore.tryAcquire();
        if (result){
            counter.incrementAndGet();
        }
        return result;
    }

    @Override
    public void release() {
        semaphore.release();
    }
}

